<template>
  <div class="page">
    <slot></slot>
    <div class="pre" @click="previousPage">&lt;</div>
    <div
      v-for="page in pageList"
      :key="page.toString()"
      class="pageItem"
      :class="[{ pageSelect: page === nowPage }, { pageEllipsis: page === -1 }]"
      @click="turnPage(page)"
    >
      {{ page == -1 ? '...' : page }}
    </div>
    <div class="next" @click="nextPage">&gt;</div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'

const emits = defineEmits<{
  (e: 'nowList', payload: Array<Object>): void
  (e: 'nowPage', payload: Number): void
}>()
const props = defineProps({
  totalList: {
    type: Array<Object>,
    default: [],
  },
  totalNum: {
    //总共有多少条数据
    type: Number,
    required: true,
    default: 0,
  },
  showNum: {
    //显示多少页
    type: Number,
    default: 9,
  },
  onePageNum: {
    //一页几条
    type: Number,
    default: 50,
  },
})

const nowPage = ref(1)
const pageList = ref([] as number[])
const totalPage = ref(0) //总共有多少页

let isNeedEllipsis = true
let midShow = 2

function init() {
  const nowList: Array<Object> = []

  totalPage.value = Math.ceil(props.totalNum / props.onePageNum)
  if (props.totalList.length) {
    for (
      let i = 0;
      i < (props.totalList.length > props.onePageNum ? props.onePageNum : props.totalList.length);
      i++
    ) {
      nowList.push(props.totalList[i])
    }

    let pages = Math.min(totalPage.value, props.showNum)
    let flag = pages >= 7 ? true : false
    isNeedEllipsis = flag && totalPage.value > props.showNum

    if (isNeedEllipsis) midShow = Math.floor((props.showNum - 4) / 2)

    for (let i = 1; i <= pages; i++) {
      if (isNeedEllipsis && i == pages - 1) {
        pageList.value.push(-1)
      } else pageList.value.push(i)
    }
    pageList.value[pageList.value.length - 1] = totalPage.value
    emits('nowList', nowList)
    emits('nowPage', nowPage.value)
  }
}

function previousPage() {
  if (nowPage.value > 1) nowPage.value--
}

function nextPage() {
  if (nowPage.value < totalPage.value) nowPage.value++
}

function turnPage(page: any) {
  if (page === -1) return
  nowPage.value = page
}

init()

watch(nowPage, (val, oldVal) => {
  const nowList: Array<Object> = []
  for (
    let i = props.onePageNum * (val - 1);
    i < Math.min(props.totalList.length, props.onePageNum * val);
    i++
  ) {
    nowList.push(props.totalList[i])
  }
  emits('nowList', nowList)
  emits('nowPage', val)

  if (!isNeedEllipsis) return

  if (val === pageList.value[0]) {
    for (let i = 2; i < props.showNum; i++) {
      if (i == props.showNum - 1) {
        pageList.value[i - 1] = -1
      } else pageList.value[i - 1] = i
    }
    return
  } else if (val === pageList.value[pageList.value.length - 1]) {
    for (let i = 2; i < props.showNum; i++) {
      if (i == 2) {
        pageList.value[i - 1] = -1
      } else pageList.value[i - 1] = totalPage.value - (props.showNum - i)
    }
    return
  }

  let nowMax =
    pageList.value[pageList.value.length - 2] == -1
      ? pageList.value[pageList.value.length - 3]
      : pageList.value[pageList.value.length - 1]
  let nowMin = pageList.value[1] == -1 ? pageList.value[2] : pageList.value[0]

  if (nowMax - val < midShow && nowMax < totalPage.value) {
    if (nowMax == pageList.value[pageList.value.length - 3]) {
      pageList.value.splice(2, 1)
      pageList.value.splice(pageList.value.length - 2, 0, nowMax + 1)
    } else {
      pageList.value.shift()
      pageList.value.push(nowMax + 1)
    }
  } else if (val - nowMin < midShow && nowMin > 1) {
    if (nowMin == pageList.value[2]) {
      pageList.value.splice(pageList.value.length - 3, 1)
      pageList.value.splice(2, 0, nowMin - 1)
    } else {
      pageList.value.pop()
      pageList.value.unshift(nowMin - 1)
    }
  }

  let m = pageList.value.length

  if (pageList.value[2] - 2 > pageList.value[0]) pageList.value[1] = -1
  else if (pageList.value[1] == -1 && pageList.value[0] + 2 == pageList.value[2]) {
    pageList.value[1] = pageList.value[0] + 1
  }

  if (pageList.value[m - 1] - 2 > pageList.value[m - 3]) {
    pageList.value[m - 2] = -1
  } else if (pageList.value[m - 2] == -1 && pageList.value[m - 3] + 2 == pageList.value[m - 1]) {
    pageList.value[m - 2] = pageList.value[m - 1] - 1
  }
})
</script>

<style lang="less" scoped>
.page {
  font-size: 3.2vh;
  color: #323130;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

.pre,
.next,
.pageItem {
  width: 5.8vh;
  height: 5.8vh;
  margin-right: 2vh;
  border-radius: 1.3vh;
  background-color: rgba(0, 10, 32, 0.05);
  line-height: 5.8vh;
}

.pageSelect {
  background: #ffffff;
  box-shadow: 0 0 0.6vh 0.3vh #f3f3f3;
}

.pageEllipsis {
  padding-top: 0.2vh;
  line-height: normal;
}
</style>
